<?php
/**
 * Describe:
 * Source:
 * User: blue
 * Time: 2018/5/27 12:05
 */

namespace app\api\service;

use app\lib\enum\ScopeEnum;
use app\lib\exception\ForbiddenException;
use app\lib\exception\TokenException;
use think\Exception;
use think\facade\Request;

class Token
{
    /**
     * 生成令牌
     * @return string
     */
    protected function produceToken(){
        //随机数+时间戳+盐 md5加密的方法,防止伪造
        $key=makeRandChar(32);
        $salt=config('security.token_salt');
        $timestap=$_SERVER['REQUEST_TIME'];
        $token=md5($key.$salt.$timestap);
        return $token;
    }
    /**
     * tokenid 获取缓存中的指定info
     * @param $key 指定的info信息 有uid openid secret
     * @return mixed
     */
    public static function tokenGetInfo($key){
        //从头部获取token
        $token=Request::header('token');
        $info=cache($token);
        //缓存中取数据失败,抛出异常.这里需要断点看后面的代码是否执行了???
        if(!$info){
            throw new TokenException();
        }
        if(!is_array($info)){
            $infoArr=json_decode($info,true);
        }
        if(!array_key_exists($key,$infoArr)){
            throw new Exception('尝试获取的Token变量并不存在');
        }else{
            return $infoArr[$key];
        }
    }

    //权限控制: 用户专有权限
    static public function userApprove(){
        //根据token获取scope
        $scope=self::tokenGetInfo('scope');
        if(!$scope){
            throw new TokenException();
        }
        if($scope==ScopeEnum::user){
            return true;
        }else{
            throw new ForbiddenException();
        }
    }
    //权限控制: 用户专有权限
    static public function superApprove(){
        $scope=self::tokenGetInfo('scope');
        if(!$scope){
            throw new TokenException();
        }
        if($scope==ScopeEnum::super){
            return true;
        }else{
            throw new ForbiddenException();
        }
    }
    //权限控制: 通用权限(user和super通用)
    static public function commonApprove(){
        //取出scope
        //scope没有值抛出异常
        //判断scope是否符合条件->否抛出异常->是返回true
        $scope=self::tokenGetInfo('scope');
        if(!$scope){
            throw new TokenException();
        }
        //scope >=ScopeEnum::user 表示当为super时也成立.
        if($scope>=ScopeEnum::user){
            return true;
        }else{
            throw new ForbiddenException();
        }
    }

    /**
     * 判断传递的id和token中获取的id是否一致
     * @param $id
     * @return bool
     * @throws Exception
     */
    static public function UserSame($id){
        if(!$id){
            //本函数为内部调用的函数,所以不需要返回给客户端
            throw new Exception('检查uid时必须传入一个被检查的uid');
        }
    //    传递过来的用户id和token中获取的tokeid是一致的
        $tokeId=self::tokenGetInfo('uid');
        if($id==$tokeId){
            return  true;
        }
        return false;
    }

    static public function tokenVerify($token){
        $tokenInfo=cache($token);
        if($tokenInfo){
            return true;
        }else{
            return false;
        }
    }

}